package myorg.myrpc;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import com.google.common.base.Throwables;
import gu.sql2java.exception.RuntimeDaoException;
import myorg.myrpc.IMyrpc;
import myorg.myrpc.ServiceSecurityException;
import myorg.myrpc.db.PersonBean;
import net.gdface.thrift.exception.ServiceRuntimeException;

/**
 * IMyrpc 服务实现
 * @author unknow_author
 *
 */
public class MyrpcImpl implements IMyrpc,ServiceConstant {
	/** 数据库操作对象，提供所有数据库访问 */
	private final DaoManagement dm = new DaoManagement();

	/**
	 * 构造方法
	 */
	public MyrpcImpl() {
	}

	////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 将封装在{@link RuntimeException}中的{@link ServiceSecurityException}剥离出来封装到{@link ServiceRuntimeException}
	 * @param error
	 * @return no return
	 * @see #throwServiceException(RuntimeException)
	 */
	protected static final ServiceRuntimeException wrapServiceRuntimeException(Exception error){
		try{
			if(error instanceof RuntimeException){
				throwServiceException((RuntimeException)error);
			}else 
				throw error;
			// dead code
			return new ServiceRuntimeException(error); 
		} catch(ServiceSecurityException e){
			return new ServiceRuntimeException(ExceptionType.SECURITY_ERROR.ordinal(),e);
		} catch(ServiceRuntimeException e){
			return e;
		} catch (Exception e) {
			return new ServiceRuntimeException(error);
		}
	}
	/**
	 * 将封装在{@link Exception}中的{@link ServiceSecurityException}剥离出来单独抛出<br>
	 * 将其他的{@link Exception}封装在{@link ServiceRuntimeException}抛出，
	 * @param error
	 * @return no return
	 * @throws ServiceSecurityException
	 */
	protected static final <T> T throwServiceException(RuntimeException error) 
			throws ServiceSecurityException{
		if(null != error.getCause()){
			try{
				throw error.getCause();
			}catch(ServiceSecurityException e){
				throw e;
			} catch (Throwable e) {
				// do nothing
			}
		}
		if(error instanceof RuntimeDaoException){
			if(error.getCause() instanceof ServiceSecurityException){
				throw (ServiceSecurityException)error.getCause();
			}
			throw new ServiceRuntimeException(ExceptionType.DAO.ordinal(),error); 
		}
		throw new ServiceRuntimeException(error); 
	}
	
	protected static final <T extends Exception> void throwCauseIfInstanceOf(Exception error,Class<T> expType) throws T {
		if(null != error.getCause()){
			Throwables.throwIfInstanceOf(error.getCause(),expType);
		}
	}

	@Override
	public PersonBean getPerson(int personId) {
		try{
			return dm.daoGetPerson(personId);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	@Override
	public List<PersonBean> getPersons(List<Integer> idList) {
		try{
			return dm.daoGetPersons(idList);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	@Override
	public PersonBean getPersonByPapersNum(String papersNum)  {
		try{
			return dm.daoGetPersonByIndexPapersNum(papersNum);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	@Override
	public PersonBean getPersonByMobilePhone(String mobilePhone)  {
		try{
			return dm.daoGetPersonByIndexMobilePhone(mobilePhone);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	
	

	@Override
	public boolean existsPerson(int persionId) {
		try{
			return dm.daoExistsPerson(persionId);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}

	@Override
	public List<Integer> loadAllPerson() {
		try{
			return dm.daoLoadPersonIdByWhere(null);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		} 
	}
	
	@Override
	public List<Integer> loadPersonIdByWhere(String where) {
		try{
			return dm.daoLoadPersonIdByWhere(where);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		} 
	}
	@Override
	public List<PersonBean> loadPersonByWhere(String where, int startRow, int numRows)  {
		try{
			return dm.daoLoadPersonByWhere(where, startRow, numRows);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	@Override
	public int countPersonByWhere(String where) {
		try{
			return dm.daoCountPersonByWhere(where);
		} catch (RuntimeException e) {
			throw wrapServiceRuntimeException(e);
		}
	}
	@Override
	public PersonBean savePerson(PersonBean personBean) {
		try{
			return dm.daoSavePerson(personBean);
		} catch (Exception e) {
			throw wrapServiceRuntimeException(e);
		}
	}

	@Override
	public int deletePerson(int personId) {
		try{
			return BaseDao.daoRunAsTransaction(new Callable<Integer>(){
				@Override
				public Integer call() throws Exception {
					return dm.daoDeletePerson(personId);
				}});
		} catch (Exception e) {
			throw wrapServiceRuntimeException(e);
		} 
	}
    	
	@Override
	public String version(){
		return Version.VERSION;
	}
    @Override
    public Map<String, String> versionInfo(){
		return Version.INFO;
	}
	@Override
	public boolean isLocal() {
		return true;
	}
}
